package com.ihr360.payroll.service.salarytask.impl;

import com.ihr360.commons.lang.CollectionUtils;
import com.ihr360.job.core.BatchStatus;
import com.ihr360.job.core.entity.JobExecution;
import com.ihr360.job.core.entity.StepExecution;
import com.ihr360.job.core.entity.StepExecutionLog;
import com.ihr360.job.core.model.ProgressInfo;
import com.ihr360.job.core.repository.JobRepository;
import com.ihr360.job.core.repository.PageData;
import com.ihr360.payroll.service.salarytask.SalaryTaskLogService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.Duration;
import java.time.Instant;
import java.util.Calendar;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class SalaryTaskLogServiceImpl implements SalaryTaskLogService {

    @Autowired
    private JobRepository jobRepository;

    @Override
    public PageData<StepExecutionLog> topLogs(List<Long> jobExecutionIds, int pageSize, long lastLogId) {
        return jobRepository.loadFirstPageLog(jobExecutionIds, pageSize, lastLogId);
    }

    @Override
    public PageData<StepExecutionLog> topLogsNoTrace(List<Long> jobExecutionIds, int pageSize, long lastLogId) {
        return jobRepository.loadFirstPageLogNoTrace(jobExecutionIds, pageSize, lastLogId);
    }

    @Override
    public PageData<StepExecutionLog> topLogsOnlyError(List<Long> jobExecutionIds, int pageSize, long lastLogId) {
        return jobRepository.loadFirstPageLogOnlyError(jobExecutionIds, pageSize, lastLogId);
    }

    @Override
    public PageData<StepExecutionLog> moreLogs(List<Long> jobExecutionIds, int pageSize, long lastLogId) {

        return jobRepository.loadLogs(jobExecutionIds, pageSize, lastLogId);
    }

    @Override
    public PageData<StepExecutionLog> moreLogsNoTrace(List<Long> jobExecutionIds, int pageSize, long lastLogId) {
        return jobRepository.loadLogsNoTrace(jobExecutionIds, pageSize, lastLogId);
    }

    @Override
    public PageData<StepExecutionLog> moreLogsOnlyError(List<Long> jobExecutionIds, int pageSize, long lastLogId) {
        return jobRepository.loadLogsOnlyError(jobExecutionIds, pageSize, lastLogId);
    }

    @Override
    public Long getErrorLogCount(List<Long> executionId) {
        return jobRepository.getErrorLogCount(executionId);
    }

    @Override
    public Long getWarningLogCount(List<Long> executionId) {
        return jobRepository.getWarningLogCount(executionId);
    }

    @Override
    public ProgressInfo getProgressInfo(Long executionId) {
        JobExecution jobExecution = jobRepository.getJobExecution(executionId);
        List<StepExecution> stepExecutions = jobRepository.getStepExecutions(jobExecution);
        BatchStatus batchStatus = jobExecution.getStatus();
//        if (BatchStatus.FAILED.equals(batchStatus) || BatchStatus.STOPPED.equals(batchStatus) || BatchStatus.ABANDONED.equals(batchStatus)) {
//            return new ProgressInfo("", "执行失败，请稍后重试...", true, false, 0);
//        }
        if (CollectionUtils.isEmpty(stepExecutions)) {
            return new ProgressInfo("", "开始执行...", false, false, 0);
        }
        //按照id降序排序，index为0的数据则是最新的执行数据
        List<StepExecution> sortedExcutions = stepExecutions.stream()
                .sorted(Comparator.comparing(StepExecution::getId).reversed()).collect(Collectors.toList());

        Calendar calendarStart = Calendar.getInstance();
        Date startTime = sortedExcutions.get(stepExecutions.size() - 1).getStartTime();
        if (startTime != null) {
            calendarStart.setTime(startTime);
        }
        Instant start = calendarStart.toInstant();

        Calendar calendarEnd = Calendar.getInstance();
        Date endTime = sortedExcutions.get(0).getEndTime();
        if (endTime != null) {
            calendarEnd.setTime(endTime);
        }
        Instant end = calendarEnd.toInstant();

        BatchStatus status = batchStatus;
        return new ProgressInfo(sortedExcutions.size() + "/" + jobExecution.getStepCount(),
                sortedExcutions.get(0).getStepName(),
                BatchStatus.COMPLETED.equals(status)
                        || BatchStatus.ABANDONED.equals(status)
                        || BatchStatus.FAILED.equals(status)
                        || BatchStatus.STOPPED.equals(status),
                BatchStatus.COMPLETED.equals(status),
                Duration.between(start, end).getSeconds());
    }

}